//
//  HMRefreshControl.swift
//  Weibo22
//
//  Created by Apple on 16/12/6.
//  Copyright © 2016年 Apple. All rights reserved.
//

import UIKit

//  下拉刷新控件的高度
private let HMRefreshControlHeight: CGFloat = 50
//  在swift里面枚举的类型可以不指定,不局限于整形
private enum HMRefreshControlType {
    //  下拉刷新
    case normal
    //  松手就刷新
    case pulling
    //  正在刷新
    case refreshing
}

//  自定义下拉刷新控件
class HMRefreshControl: UIControl {
    
    //  记录当前刷新的状态
    private var refreshType: HMRefreshControlType = .normal {
        didSet {
            switch refreshType {
            case .normal:
                // 下拉刷新
                print("下拉刷新")
                //  显示箭头, 箭头重置, 停止风火轮,文字改成下拉刷新
                iconImageView.isHidden = false
                indicatorView.stopAnimating()
                //  箭头重置
                
                UIView.animate(withDuration: 0.25, animations: {
                    
                    self.iconImageView.transform = CGAffineTransform.identity
                    
                })
                messageLabel.text = "下拉刷新"
                
                //  判断上一次的刷新状态是正在刷新,让其设置成原始位置
                //  oldValue 表示上一次设置的状态
                if oldValue == .refreshing {
                    //  设置刷新控件的停留位置
                    UIView.animate(withDuration: 0.25, animations: {
                        self.currentScrollView?.contentInset.top -= HMRefreshControlHeight
                    })
                }
                
                
                
                
            case .pulling:
                //  松手就刷新
                print("松手就刷新")
                //  箭头调转,文字改成松手就刷新状态
                
                UIView.animate(withDuration: 0.25, animations: { 
                    
                    self.iconImageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI))
                    
                })
                
                messageLabel.text = "松手就刷新"
                
                
                
                
                
            case .refreshing:
                //  正在刷新
                print("正在刷新")
                //  隐藏箭头, 开启风火轮, 文字改为正在刷新
                iconImageView.isHidden = true
                indicatorView.startAnimating()
                messageLabel.text = "正在刷新..."
                
                //  设置刷新控件的停留位置
                UIView.animate(withDuration: 0.25, animations: { 
                    self.currentScrollView?.contentInset.top += HMRefreshControlHeight
                })
                
                
                //  发送事件让外界刷新数据
                sendActions(for: .valueChanged)
                
            }
        }
    
    }
    
    //  记录当前可以滚动的视图
    private var currentScrollView: UIScrollView?
    
    //  MARK: -- 懒加载控件
    //  箭头icon
    fileprivate lazy var iconImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //  风火轮
    fileprivate lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    //  信息文字
    fileprivate lazy var messageLabel: UILabel = {
        let label = UILabel()
        label.text = "下拉刷新"
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = UIColor.gray
        return label
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //  添加控件设置约束
    private func setupUI() {
        backgroundColor = UIColor.red
        addSubview(iconImageView)
        addSubview(indicatorView)
        addSubview(messageLabel)
        
        //  使用代码方法布局
        iconImageView.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: iconImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
        
        addConstraint(NSLayoutConstraint(item: iconImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: iconImageView, attribute: .centerX, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: iconImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: iconImageView, attribute: .trailing, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: iconImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
        
        
    }
    
    //  当你添加到父视图的时候回调用这个方法
    override func willMove(toSuperview newSuperview: UIView?) {
        //  判断我的父视图是否是可以滚动的控件
        guard let scrollView = newSuperview as? UIScrollView else {
            return
        }
        
        //  设置当前视图的大小
        self.frame.size = CGSize(width: scrollView.frame.size.width, height: HMRefreshControlHeight)
        self.frame.origin.y = -HMRefreshControlHeight

        
        //  使用kvo
        // 使用kvo监听contentOffset的值得改变
        scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
        
        currentScrollView = scrollView
    }
    //  kvo监听方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        //  获取垂直方向Y的偏移量
        //  需要使用scrollView 获取偏移量
        let contentOffY = currentScrollView!.contentOffset.y
        
        //  1. 计算临界点 -114
        let maxY: CGFloat = -(currentScrollView!.contentInset.top + HMRefreshControlHeight)
        
        //  怎么判断是否松手
        if currentScrollView!.isDragging {
            
            //  只有两种刷新状态, 1. 下拉状态, 2. 松手就刷新的状态
            if contentOffY < maxY && refreshType == .normal {
                //  设置状态
                refreshType = .pulling
                
            } else if contentOffY >= maxY && refreshType == .pulling {
                refreshType = .normal
                
            }
            
            
            
            
            
        } else {
            if refreshType == .pulling {
                refreshType = .refreshing
                
            }
            
            
        }
        
        
        
        
    }
    
    //  结束刷新
    func endRefreshing() {
        refreshType = .normal
    }
    
    
    
    //  移除kvo
    deinit {
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    
    
    
    
    
    
    
    

}
